﻿using FastCloud.Base.Desgin;
using FastORM.Applicaiton;
using FastORM.Enum;
using FastUtil.Config;
using FastUtil.Convert;
using FastUtil.Data;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using IApplicationLifetime = Microsoft.AspNetCore.Hosting.IApplicationLifetime;

namespace FastCloud.Base.Config
{
    public class CloudUtil
    {
        private static CommonDao CommonDao = new CommonDao(DataBaseClass.MySql, CloudUtil.GetBaseConnectString());
        private static IWebHostEnvironment Env;
        private static IMvcBuilder BUD;
        private static IHost Host;
        private static IApplicationLifetime APP;

        public static void SetEnviroment(IWebHostEnvironment EnvParam)
        {
            Env = EnvParam;
            PathUtil.SetAppPath(GetContentPath());
        }

        public static void SetBuilder(IMvcBuilder Builder)
        {
            BUD = Builder;
        }

        public static void SetHost(IHost WebHost)
        {
            Host = WebHost;
        }

        public static void SetAPP(IApplicationLifetime applicationLifetime)
        {
            APP = applicationLifetime;
        }

        public static IApplicationLifetime GetApp()
        {
            return APP;
        }

        public static IMvcBuilder GetBuilder()
        {
            return BUD;
        }

        public static IWebHostEnvironment GetEnviroment()
        {
            return Env;
        }

        public static void Restrat()
        {
            APP.StopApplication();
        }

        public static string GetContentPath()
        {
            if (Env!=null)
            {
                return Env.ContentRootPath;
            }
            else
            {
                return System.Environment.CurrentDirectory;
            }
            
        }

        public static string GetContentStaticFilePath()
        {
            var path = CloudUtil.GetContentPath() + "/StaticFile/";
            return path;
        }

        public static string GetAttachUploadPath(string Group)
        {
            var path = CloudUtil.GetContentStaticFilePath() + "/" + AppConfigUtil.Configuration["Attach:AttachUploadPath"] + "/";
            if (!string.IsNullOrEmpty(Group))
            {
                path += "/" + Group;
            }
            path += "/" + DateTime.Now.ToString("yyyy-MM-dd");
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            return path;
        }

        public static string GetAttachTempPath()
        {
            return  "StaticFile/" + AppConfigUtil.Configuration["Attach:AttachUploadPath"];
        }

        public static string GetAttachVirtualPath()
        {
            return "StaticFile/" + AppConfigUtil.Configuration["Attach:AttachVirtualPath"]; 
        }


        public static string GetBaseConnectString()
        {
            return AppConfigUtil.Configuration["ConnectionStrings:Cloud_ConnectionString"];
        }

        public static string GetAttachStorageType()
        {
            return AppConfigUtil.Configuration["Attach:AttachStorageType"];
        }

        public static string GetRootPath()
        {
            //协议
            string Scheme = CloudContext.Current.Request.Scheme;
            //域名
            string Host = CloudContext.Current.Request.Host.Value;
            //工程名
            string ApplicationPath = CloudContext.Current.Request.PathBase;
            string RootPath = string.Empty;
            RootPath = Scheme + "://" + Host + ApplicationPath + "/";
            return RootPath;
        }
        public static string GetClientIP()
        {
            return CloudContext.Current.Connection.RemoteIpAddress.ToString();
        }
        public static int GetRedisCacheDBNum()
        {
            return ValueConvert.ConvertToInt32(AppConfigUtil.Configuration["Redis:RedisCacheDBNum"]);
        }

        public static bool CheckIsAnonymousAccess(string url)
        {
            bool flag = false;
            var ValuesSection = AppConfigUtil.Configuration.GetSection("AnonymousAccess");
            foreach (IConfigurationSection section in ValuesSection.GetChildren())
            {
                var SettingUrl = section.GetValue<string>("Url");
                if (url.Contains(SettingUrl))
                {
                    flag = true;
                    break;
                }
            }
            return flag;
        }

        public static bool CheckIsRequestLog(string url)
        {
            if (!url.StartsWith("/"))
            {
                url = "/" + url;
            }
            bool flag = false;
            var ValuesSection = AppConfigUtil.Configuration.GetSection("Frame:RequestLogRoute");
            foreach (IConfigurationSection section in ValuesSection.GetChildren())
            {
                if (section.Value.Contains(url) || url.Contains(section.Value))
                {
                    flag = true;
                    break;
                }
            }
            return flag;
        }

        public static List<Assembly> GetFrameworkAssemblys()
        {
            var list = new List<Assembly>();
            var deps = DependencyContext.Default;
            var libs = deps.CompileLibraries;
            foreach (var lib in libs)
            {
                if (!lib.Serviceable && lib.Type != "package" && lib.Name.StartsWith("FastCloud"))
                {
                    var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
                    list.Add(assembly);
                }
            }
            return list;
        }


        public static string GetFormParam(string ParamName)
        {
            string Value = string.Empty;
            try
            {
                StringValues ParamValues;
                CloudContext.Current.Request.Form.TryGetValue(ParamName, out ParamValues);
                if (ParamValues.Count > 0)
                {
                    Value =  ParamValues[0];
                }
            }
            catch (Exception)
            {

                
            }
            return Value;
        }

        public static string GetUrlParam(string ParamName)
        {
            return CloudContext.Current.Request.Query[ParamName];
        }

        public static List<TreeNode> BuildTree(List<TreeNode> AllTreeNode)
        {
            List<TreeNode> TopNodeList = CopyUtil.CopyList<TreeNode>(AllTreeNode.FindAll((TreeNode node) => node.IsTop));
            foreach (TreeNode item in TopNodeList)
            {
                BuildSub(AllTreeNode, item);
            }
            return TopNodeList;
        }
        public static List<TreeNode> BuildGroupTree(List<TreeNode> AllTreeNode)
        {
            List<TreeNode> TopNodeList = CopyUtil.CopyList<TreeNode>(AllTreeNode.FindAll((TreeNode node) => node.IsTop));
            foreach (TreeNode item in TopNodeList)
            {
                BuildSub(AllTreeNode, item);
            }
            foreach (TreeNode item in TopNodeList)
            {
                item.ID = "Top";
            }
            return TopNodeList;
        }
        public static void BuildSub(List<TreeNode> AllTreeNode, TreeNode NowNode)
        {
            List<TreeNode> ChildNodeList = CopyUtil.CopyList<TreeNode>(AllTreeNode.FindAll((TreeNode node) => node.PID == NowNode.ID));
            if (ChildNodeList.Count > 0)
            {
                NowNode.IsParent = true;
            }
            foreach (TreeNode item in ChildNodeList)
            {
                BuildSub(AllTreeNode, item);
                NowNode.AddChildNode(item);
            }
        }
        public static string CreateTableFieldCodeValue(string TableName, string KeyFieldName, string CodeFieldName, string ParentGuidName, string ParentGuid,string DefaultCode="1000")
        {
            string Code = string.Empty;
            if (ParentGuid == "Top")
            {
                string SQL = string.Format("select max({0}) from {1} where {2}='Top'", CodeFieldName, TableName, ParentGuidName);
                string RecordCode = CommonDao.ExecuteToString(SQL);
                if (string.IsNullOrEmpty(RecordCode))
                {
                    Code = DefaultCode;
                }
                else
                {
                    Code = (Convert.ToInt64(RecordCode) + 1).ToString();
                }
            }
            else
            {
                CommonRow record = new CommonRow(TableName, KeyFieldName, ParentGuid, DataBaseClass.MySql, CloudUtil.GetBaseConnectString());
                string ParentCode = Convert.ToString(record[CodeFieldName]);
                string SQL = string.Format("select max({0}) from {1} where LENGTH({0})={2} and {0} like '{3}%'", CodeFieldName, TableName, ParentCode.Length + 4, ParentCode);
                string RecordCode = CommonDao.ExecuteToString(SQL);
                if (string.IsNullOrEmpty(RecordCode))
                {
                    Code = ParentCode + "1000";
                }
                else
                {
                    Code = (Convert.ToInt64(RecordCode) + 1).ToString();
                }

            }
            return Code;
        }

        public static bool CheckOpenVerifyCode()
        {
            return ValueConvert.ConvertToString(AppConfigUtil.Configuration["Frame:OpenVerifyCode"]) == "1";
        }

        public static string CreateRandomCode(int codeLen)
        {
            string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            string[] allCharAry = allChar.Split(',');
            string randomCode = "";
            int temp = -1;
            Random rand = new Random();
            for (int i = 0; i < codeLen; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(35);
                if (temp == t)
                {
                    return CreateRandomCode(codeLen);
                }
                temp = t;
                randomCode += allCharAry[t];
            }
            return randomCode;
        }
    }
}
